package com.googlecode.cswish.security.type;

import org.apache.commons.lang.ObjectUtils;

import com.googlecode.cswish.security.Context;
import com.googlecode.cswish.util.FreemarkerTplEngine;

import freemarker.template.SimpleHash;

/**
 * Rule is a freemarker template, contains 2 kinds of logic:<p>
 * 
 * 1. whereCondition for the sql permission<br>
 * 2. condition for the field permission<br>
 * <p>
 * all the sql permission must have the field permission, but the field permission can skip the sql permission(
 * see UserService.loginUser)
 * 
 * @author Jerry.Feng Date: 2008-6-10
 */
public class FreemarkerSQLRule implements PermissionRule {

	private String name;
	
	private String condition;
	
	private String fromClause;
	
	private String whereCondition;
	
	@Override
	public void setCondition(String condition) {
		this.condition = condition;
	}

	@Override
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * condition == true, means the limit is valid, user has the permission to visit it.
	 */
	@Override
	public String execute(Context context) {
		if (whereCondition != null) {
			return execute(context, true);
		} else {
			// TODO: use a new class implements the FreemarkerRule logic? see UserService.addReadLimition
			// FreemarkerSQLRule contains the FreemarkerRule logic and SQL clause logic
			return execute(context, false);
		}
	}
	
	private String execute(Context context, boolean isSQL) {
		String value = null;
		if (context != null) {
			String cond = isSQL ? whereCondition : condition;
			
			if (cond != null) {
				FreemarkerTplEngine engine = FreemarkerTplEngine.getInstance();
				
				SimpleHash model = context.toTemplateModel();
				value = engine.execute(cond, model);
			}
		}
		return value;
	}

	@Override
	public boolean executeBoolean(Context context) {
		String ret = execute(context, false);
		return Boolean.valueOf(ret);
	}

	public String getFromClause() {
		return fromClause;
	}

	@Override
	public void setFromClause(String fromClause) {
		this.fromClause = fromClause;
	}

	public String getWhereCondition() {
		return whereCondition;
	}

	@Override
	public void setWhereCondition(String whereCondition) {
		this.whereCondition = whereCondition;
	}

	public boolean equals(Object obj) {
		if (obj instanceof FreemarkerSQLRule) {
			FreemarkerSQLRule another = (FreemarkerSQLRule) obj;
			return ObjectUtils.equals(name, another.name) && ObjectUtils.equals(condition, another.condition)
				&& ObjectUtils.equals(fromClause, another.fromClause)
				&& ObjectUtils.equals(whereCondition, another.whereCondition);
		} else {
			return false;
		}
	}

	@Override
	public String getCondition(boolean booleanCondition) {
		return booleanCondition ? condition : whereCondition;
	}
}